package com.xjy.rpc.proxy.jdk;

import com.xjy.rpc.cache.ChannelCache;
import com.xjy.rpc.netty.message.RpcRequest;
import com.xjy.rpc.netty.message.RpcMessage;
import com.xjy.rpc.proxy.IProxy;
import io.netty.channel.Channel;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
 * @description: TODO jdk动态代理是代理接口实现的，选用此代理模式需要实现接口,接收也用接口
 * @author XJY
 * @date 2024/9/30 10:09
 * @version 1.0
 */
@Component
public class JdkProxyFactory implements IProxy {

    @Override
    public <T> T getProxy(Class<T> clazz) {
        return getBean(clazz);
    }

    public <T> T getBean(Class<T> clazz){
        Object o = Proxy.newProxyInstance(JdkProxyFactory.class.getClassLoader(),
                clazz.getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        RpcMessage rpcMessage = new RpcMessage();
                        rpcMessage.setRequestId(new Random().nextLong());
                        rpcMessage.setMessageType((short) 0x10);
                        rpcMessage.setExpireTime(100);
                        rpcMessage.setUnit(TimeUnit.SECONDS);
                        RpcRequest body = new RpcRequest();
                        body.setIp("127.0.0.1");
                        body.setPort(8083);
                        body.setInterfaceName("com.xjy.rpc.controller.testController");
                        body.setMethodName("hello");
                        body.setMethodResponseType("String");
                        rpcMessage.setBody(body);
                        //TODO 这里需要缓存netty连接channel
                        Channel channel = ChannelCache.channelMap.get("10.14.0.32");
                        channel.writeAndFlush(rpcMessage);
                        Object result = method.invoke(clazz.newInstance(),args);
                        return result;
                    }
                });
        return (T) o;
    }
 }
